package com.atguigu.spzx.manager.service.impl;

import com.atguigu.spzx.common.exp.GuiguException;
import com.atguigu.spzx.manager.mapper.SysMenuMapper;
import com.atguigu.spzx.manager.service.SysMenuService;
import com.atguigu.spzx.model.dto.system.AssginMenuDto;
import com.atguigu.spzx.model.entity.system.SysMenu;
import com.atguigu.spzx.model.vo.common.ResultCodeEnum;
import com.atguigu.spzx.model.vo.system.SysMenuVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Service
public class SysMenuServiceImpl implements SysMenuService {


    @Autowired
    SysMenuMapper sysMenuMapper;
    @Override
    public List<SysMenu> menuListByParentId(long parentId) {
       //select * from sys_Menu where parentId  =0 查询一级列表
      List<SysMenu> menuList =   sysMenuMapper.findByParentId(parentId);

      if(!CollectionUtils.isEmpty(menuList)){
          //遍历menulist 菜单
          menuList.forEach(sysMenu -> {
              //递归调用根据自己的id 查询的是下级菜单list
                List<SysMenu> children = this.menuListByParentId(sysMenu.getId());
                //判断下级菜单 有值给sysMenu赋值
                sysMenu.setChildren(CollectionUtils.isEmpty(children)?null:children);
          });
      }
      return menuList;
    }

    public void deleteMenu(Long menuId){
        //1.判断当前菜单是否存在下级，如果存在抛出异常，该菜单存在下级，暂不允许删除！
        //1、判断当前菜单是否存在下级，如果存在抛出异常，该菜单存在下级，暂不允许删除！
        List<SysMenu> byParentId = sysMenuMapper.findByParentId(menuId);//查询当前菜单的下级菜单列表
        if(byParentId!=null && byParentId.size()>0){
            //有下级
            throw new GuiguException(ResultCodeEnum.NODE_ERROR);
        }

        //2、如果不存在，则逻辑删除
        sysMenuMapper.deleteByMenuId(menuId);
    }
    @Override
    public void deleteMenu2(Long menuId) {
        //1.先删除当前菜单
        sysMenuMapper.deleteByMenuId(menuId);
        //2.查询一级菜单集合 当前id集合
        List<SysMenu> children = sysMenuMapper.findByParentId(menuId);
        //3.长度大于1证明有子菜单
        if(children!=null&&children.size()>0){
            //遍历把子菜单也删除 用户信息
            children.forEach(sysMenu -> {
                //递归调用
                this.deleteMenu2(sysMenu.getId());
            });
        }
    }

    @Override
    public void addMenu(SysMenu sysMenu) {
        sysMenuMapper.addMenu(sysMenu);
    }

    @Override
    public void updateMenu(SysMenu sysMenu) {
        //无论是添加还是修改：
        //1、必要字段做非空校验（菜单标题）
        //2、菜单名称的唯一性校验

        sysMenuMapper.updateMenu(sysMenu);
    }

    @Override
    public Map getMenuListAndMenuIdList(Long roleId) {

        Map map = new HashMap();
        //查询菜单表
        map.put("menuList",this.menuListByParentId(0L));//一级菜单列表（包含子菜单集合）

        //查询复选框为0的菜单
        List<Long> menuIdList = sysMenuMapper.getMenuIdList(roleId);
        map.put("menuIdList",menuIdList);//SELECT menu_id FROM `sys_role_menu` WHERE is_half = 0 AND role_id = #{roleId}

        return map;
    }

    @Override
    public void doAssignMenu(AssginMenuDto menuDto) {
        //1、根据roleId从关系表中删除  DELETE FROM `sys_role_menu`   WHERE role_id = 9
        sysMenuMapper.deleteByRoleId(menuDto.getRoleId());
        //2、重新建立 将数据转换我menuDto的对象
        List<Map<String, Number>> menuIdList = menuDto.getMenuIdList();
        menuIdList.forEach(map->{
            Number menuId = map.get("menuId");
            Number isHalf = map.get("isHalf");

            sysMenuMapper.doAssignRoleMenu(menuDto.getRoleId() , menuId , isHalf);
        });
    }

    @Override
    //传递两个参数 是在数据库中查询一级菜单 需要用的参数 roleId parentId
    public List<SysMenuVo> getMenuListByUserId(Long userId, Long parentId) {
        //1.一级菜单列表 每个菜单具有children赋值
         List<SysMenu> sysMenuList =   this.findSysMenuList(userId, parentId);
        //2.每个SysMenu 转成SysMenuVo
        List<SysMenuVo> sysMenuVoList =   this.sysMenuListToVoList(sysMenuList);

        return  sysMenuVoList;
    }


    private List<SysMenuVo> sysMenuListToVoList(List<SysMenu> sysMenuList) {
       //创建SysMenuVo容器
        List<SysMenuVo> sysMenuVoList = new ArrayList<>();
        sysMenuList.forEach(sysMenu -> {
            //每个SysMenu转成 SysMenuVo
            SysMenuVo sysMenuVo = new SysMenuVo();
            sysMenuVo.setTitle(sysMenu.getTitle());
            sysMenuVo.setName(sysMenu.getComponent());

            //判断children不为空时,才进行children的转成
            if(!CollectionUtils.isEmpty(sysMenu.getChildren())){
                //因为children是集合 得用list去接受
                List<SysMenuVo> childrenSysMenuVo = this.sysMenuListToVoList(sysMenu.getChildren());
                sysMenuVo.setChildren(childrenSysMenuVo);
            }
                sysMenuVoList.add(sysMenuVo);
        });
        return sysMenuVoList;
    }

    //创建两个私有方法
    private List<SysMenu> findSysMenuList(Long userId, Long parentId){
        //一级列表列表
       List<SysMenu> sysMenuList = sysMenuMapper.findSysMenuList(userId,parentId);

       sysMenuList.forEach(sysMenu ->{
           List<SysMenu> children = this.findSysMenuList(userId,sysMenu.getId());
           if(!CollectionUtils.isEmpty(children)){
               sysMenu.setChildren(children);
           }
       });
       return sysMenuList;
    }
}
